import sys
from bisect import bisect_left

input = sys.stdin.read
data = input().split()
idx = 0
n = int(data[idx])
idx += 1
a = list(map(int, data[idx:idx + n]))
idx += n
m = int(data[idx])
idx += 1

# 分块
block_size = int(n**0.5) + 1  # 块的大小
num_blocks = (n + block_size - 1) // block_size  # 块的数量

blocks = []
lazy = [0] * num_blocks
for i in range(num_blocks):
    start = i * block_size
    end = min((i + 1) * block_size, n)
    block = a[start:end]
    block.sort()
    blocks.append(block)

for _ in range(m):
    op = data[idx]
    idx += 1
    l = int(data[idx]) - 1
    r = int(data[idx + 1]) - 1
    x = int(data[idx + 2])
    idx += 3

    left_block = l // block_size
    right_block = r // block_size

    if op == '1':
        # 区间加法，遍历块数
        for i in range(left_block, right_block + 1):
            block_start = i * block_size
            block_end = min((i + 1) * block_size, n)
            cur_l = max(l, block_start)
            cur_r = min(r, block_end - 1)  # 不包含右区间

            # 无效选择，跳过
            if cur_l > cur_r:
                continue

            # 整个块被包含
            if cur_l == block_start and cur_r == block_end - 1:
                lazy[i] += x
            else:
                # 部分块，需要重建
                block_start = i * block_size
                block_end = min((i + 1) * block_size, n)
                # 应用之前的lazy
                if lazy[i] != 0:
                    for j in range(block_start, block_end):
                        a[j] += lazy[i]
                    lazy[i] = 0
                # 更新区间
                for j in range(cur_l, cur_r + 1):
                    a[j] += x
                # 重建块
                blocks[i] = a[block_start:block_end]
                blocks[i].sort()
    else:
        # 查询操作
        ans = 0
        for i in range(left_block, right_block + 1):
            block_start = i * block_size
            block_end = min((i + 1) * block_size, n)
            cur_l = max(l, block_start)
            cur_r = min(r, block_end - 1)

            if cur_l > cur_r:
                continue

            # 整个块被包含
            if cur_l == block_start and cur_r == block_end - 1:
                target = x - lazy[i]
                cnt = bisect_left(blocks[i], target)
                ans += cnt
            else:
                # 部分块，需要逐个检查
                if lazy[i] != 0:
                    for j in range(block_start, block_end):
                        a[j] += lazy[i]
                    lazy[i] = 0
                    # 重建块
                    blocks[i] = a[block_start:block_end]
                    blocks[i].sort()
                for j in range(cur_l, cur_r + 1):
                    if a[j] < x:
                        ans += 1
        print(ans)